#include "view.h"
#include "script.h"
#include "resource.h"
#include "log.h"

#include "lualib.h"
#include "lua.h"
#include "lauxlib.h"

#include <string.h>
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include <assert.h>

extern lua_State* g_ufo_lua_state;

static int lua_ufoViewGetMargin(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	ufoRect rect = {0};
	ufoViewGetMargin(view, &rect);
	//lua_newtable(L);

	//ufoViewSetAlpha(view, alpha);
	lua_pushinteger(L, rect.left);
	lua_pushinteger(L, rect.top);
	lua_pushinteger(L, rect.right);
	lua_pushinteger(L, rect.bottom);

	return 4;
}

static int lua_ufoViewGetRect(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	ufoRect rect = {0};
	ufoViewGetRect(view, &rect);
	//lua_newtable(L);

	//ufoViewSetAlpha(view, alpha);
	lua_pushinteger(L, rect.left);
	lua_pushinteger(L, rect.top);
	lua_pushinteger(L, rect.right);
	lua_pushinteger(L, rect.bottom);

    ufoLog("lua", "lua_ufoViewGetRect");
    
	return 4;
}

static int lua_ufoViewSetBackground(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	const char *background = lua_tostring(L, -1);
	
	UFO_Texture tex = ufoResourceGetTexture(background);
	ufoViewSetBackground(view, tex);
	lua_pushinteger(L, 1);

	return 1;
}

static int lua_ufoViewSetId(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	const char *id = lua_tostring(L, -1);

	ufoViewSetId(view, id);
	lua_pushinteger(L, 1);

	return 1;
}

static int lua_ufoViewSetHidden(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	int bHidden = lua_toboolean(L, -1);

	ufoViewSetMask(view, UFO_VIEW_BIT_HIDDEN, bHidden);
	lua_pushinteger(L, 1);

	return 1;
}

static int lua_ufoViewSetOnRectChange(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	const char *script = lua_tostring(L, -1);
	lua_pushinteger(L, ufoViewSetOnRectChange(view, script));
	return 1;
}

static int lua_ufoViewSetOnAnimationFinish(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	const char *script = lua_tostring(L, -1);
	lua_pushinteger(L, ufoViewSetOnAnimationFinish(view, script));
	return 1;
}

static int lua_ufoViewSetOnTouchDown(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	const char *script = lua_tostring(L, -1);
	lua_pushinteger(L, ufoViewSetOnTouchDown(view, script));
	return 1;
}

static int lua_ufoViewSetOnClick(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	const char *script = lua_tostring(L, -1);
	lua_pushinteger(L, ufoViewSetOnClick(view, script));
	return 1;
}

static int lua_ufoViewSetOnTouchUp(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	const char *script = lua_tostring(L, -1);
	lua_pushinteger(L, ufoViewSetOnTouchUp(view, script));
	return 1;
}

static int lua_ufoViewGetId(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");

	lua_pushstring(L, ufoViewGetId(view));

	return 1;
}

static int lua_ufoViewAddChildView(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	UFO_View *pHandle = lua_touserdata(L, 2);
    UFO_View childView = pHandle ? *pHandle : 0;

	lua_pushinteger(L, ufoViewAddChildView(view, childView));

	return 1;
}

static int lua_ufoViewSetMargin(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	ufoRect rect = {0};
	rect.left = lua_tonumber(L, 2);
	rect.top = lua_tonumber(L, 3);
	rect.right = lua_tonumber(L, 4);
	rect.bottom = lua_tonumber(L, 5);

	ufoViewSetMargin(view, &rect);
	lua_pushinteger(L, 1);

	return 1;
}

static int lua_ufoViewSetAnchor(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	const char *textanchor = lua_tostring(L, -1);

	UFO_LAYOUT_ANCHOR anchor = 0;
	if (strstr((const char*)textanchor, "ANCHOR_LEFT"))
		anchor |= ANCHOR_LEFT;

	if (strstr((const char*)textanchor, "ANCHOR_TOP"))
		anchor |= ANCHOR_TOP;

	if (strstr((const char*)textanchor, "ANCHOR_RIGHT"))
		anchor |= ANCHOR_RIGHT;

	if (strstr((const char*)textanchor, "ANCHOR_BOTTOM"))
		anchor |= ANCHOR_BOTTOM;

	//if (strstr((const char*)textanchor, "ANCHOR_CENTER"))
	//	anchor |= ANCHOR_CENTER;

	if (strstr((const char*)textanchor, "ANCHOR_CENTER_HORZ"))
		anchor |= ANCHOR_CENTER_HORZ;

	if (strstr((const char*)textanchor, "ANCHOR_CENTER_VERT"))
		anchor |= ANCHOR_CENTER_VERT;

	ufoViewSetAnchor((UFO_View)view, anchor);
	/*ufoRect rect = {0};
	rect.left = lua_tonumber(L, 2);
	rect.top = lua_tonumber(L, 3);
	rect.right = lua_tonumber(L, 4);
	rect.bottom = lua_tonumber(L, 5);*/

	//ufoViewSetMargin(view, &rect);
	lua_pushinteger(L, 1);

	return 1;
}

static int lua_ufoViewSetRect(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	ufoRect rect = {0};
	rect.left = lua_tonumber(L, 2);
	rect.top = lua_tonumber(L, 3);
	rect.right = lua_tonumber(L, 4);
	rect.bottom = lua_tonumber(L, 5);

	ufoViewSetRect(view, &rect);
	lua_pushinteger(L, 1);

	return 1;
}

static int lua_ufoViewGetAlpha(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");

	lua_pushnumber(L, ufoViewGetAlpha(view));
	return 1;
}

static int lua_ufoViewSetAlpha(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	float alpha = (float)lua_tonumber(L, 2);

	ufoViewSetAlpha(view, alpha);
	lua_pushinteger(L, 1);

	return 1;
}

static int lua_ufoViewSetBackgroundColor(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	float red = (float)lua_tonumber(L, 2);
	float green = (float)lua_tonumber(L, 3);
	float blue = (float)lua_tonumber(L, 4);
	float alpha = (float)lua_tonumber(L, 5);
	ufoColor color = {red, green, blue, alpha};
	lua_pushinteger(L, ufoViewSetBackgroundColor(view, &color));
	return 1;
}

static int lua_ufoViewGetBackgroundColor(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	ufoColor *color = ufoViewGetBackgroundColor(view);
	if (color) {
		lua_pushnumber(L, color->red);
		lua_pushnumber(L, color->green);
		lua_pushnumber(L, color->blue);
		lua_pushnumber(L, color->alpha);
		return 4;
	}
	else {
		lua_pushnumber(L, 0);
		lua_pushnumber(L, 0);
		lua_pushnumber(L, 0);
		lua_pushnumber(L, 0);
		return 4;
	}

	return 0;
}

static int lua_ufoViewSetAutoSize(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	int bAuto = (int)lua_toboolean(L, 2);

	ufoViewSetMask(view, UFO_VIEW_BIT_AUTOSIZE, bAuto);
	//ufoViewSetAlpha(view, alpha);
	lua_pushinteger(L, 1);

	return 1;
}

static int lua_ufoViewSetZorder(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	float zOrder = (float)lua_tonumber(L, 2);

	lua_pushinteger(L, ufoViewSetZorder(view, zOrder));

	return 1;
}

static int lua_ufoViewSetGesture(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	int bGesture = (int)lua_toboolean(L, 2);
	ufoLog("lua_ufoViewSetGesture", "lua_ufoViewSetGesture view=%x bSet=%d", view, bGesture);
	assert(0);//### not support now
    //lua_pushinteger(L, ufoViewSetMask(view, UFO_VIEW_BIT_GESTURE, bGesture));
	return 1;
}

static int lua_ufoViewSetClipsTobounds(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	int clipsTobounds = (int)lua_toboolean(L, 2);

	ufoViewSetMask(view, UFO_VIEW_BIT_CLIPSTOBOUNDS, clipsTobounds);
	lua_pushinteger(L, 1);

	return 1;
}

static int lua_ufoViewGetChild(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	UFO_View child = ufoViewGetChild(view);

	*(void**)lua_newuserdata(L, sizeof(void*)) = child;
	luaL_getmetatable(L, "ufo.ufoView");
	lua_setmetatable(L, -2);

	return 1;
}

static int lua_ufoViewGetChildByIndex(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	int nIndex = lua_tonumber(L, 2);
	UFO_View child = ufoViewGetChildByIndex(view, nIndex);

	*(void**)lua_newuserdata(L, sizeof(void*)) = child;
	luaL_getmetatable(L, "ufo.ufoView");
	lua_setmetatable(L, -2);

	return 1;
}

static int lua_ufoViewGetParent(lua_State *L)
{
	UFO_View view = *(UFO_View*)luaL_checkudata(L, 1, "ufo.ufoView");
	UFO_View parent = ufoViewGetParent(view);

	*(void**)lua_newuserdata(L, sizeof(void*)) = parent;
	luaL_getmetatable(L, "ufo.ufoView");
	lua_setmetatable(L, -2);
    
    ufoLog("lua", "lua_ufoViewGetParent");
    
	return 1;
}

static int lua_ufoViewGetFromId(lua_State *L)
{
    UFO_View *pHandle = lua_touserdata(L, -2);
	UFO_View parentView = pHandle ? *pHandle : 0;
	const char *id = lua_tostring(L, -1);

	UFO_View view = ufoViewGetFromId(parentView, id);
	
	*(void**)lua_newuserdata(L, sizeof(void*)) = view;

	luaL_getmetatable(L, "ufo.ufoView");
	lua_setmetatable(L, -2);

	return 1;
}

static int lua_ufoViewCreate(lua_State *L)
{
	const char *id = lua_tostring(L, -1);
	UFO_View view = ufoViewCreate(id);

	*(void**)lua_newuserdata(L, sizeof(void*)) = view;

	luaL_getmetatable(L, "ufo.ufoView");
	lua_setmetatable(L, -2);

	return 1;
}

static const struct luaL_Reg viewlib_c [] = {
	{"getFromId", lua_ufoViewGetFromId},
	{"create", lua_ufoViewCreate},
	{0, 0},
};

static const struct luaL_Reg viewlib [] = {
	{"setAlpha", lua_ufoViewSetAlpha},
	{"setId", lua_ufoViewSetId},
	{"setAutoSize", lua_ufoViewSetAutoSize},
	{"setHidden", lua_ufoViewSetHidden},
	{"setOnClick", lua_ufoViewSetOnClick},
	{"setOnTouchDown", lua_ufoViewSetOnTouchDown},
	{"setOnTouchUp", lua_ufoViewSetOnTouchUp},
	{"setOnAnimationFinish", lua_ufoViewSetOnAnimationFinish},
	{"setOnRectChange", lua_ufoViewSetOnRectChange},
	{"getId", lua_ufoViewGetId},
	{"setRect", lua_ufoViewSetRect},
	{"setMargin", lua_ufoViewSetMargin},
	{"setAnchor", lua_ufoViewSetAnchor},
	{"getRect", lua_ufoViewGetRect},
	{"getAlpha", lua_ufoViewGetAlpha},
	{"getMargin", lua_ufoViewGetMargin},
	{"getParent", lua_ufoViewGetParent},
	{"getChild", lua_ufoViewGetChild},
	{"getChildByIndex", lua_ufoViewGetChildByIndex},
	{"addChildView", lua_ufoViewAddChildView},
	{"setBackground", lua_ufoViewSetBackground},
	{"setClipsTobounds", lua_ufoViewSetClipsTobounds},
	{"setGesture", lua_ufoViewSetGesture},
	{"setZorder", lua_ufoViewSetZorder},
	{"setBackgroundColor", lua_ufoViewSetBackgroundColor},
	{"getBackgroundColor", lua_ufoViewGetBackgroundColor},
	{0, 0},
};

int internal_initializationScript_view()
{
	if (!g_ufo_lua_state) {
		g_ufo_lua_state = luaL_newstate();
		luaL_openlibs(g_ufo_lua_state);
	}

	luaL_newmetatable(g_ufo_lua_state, "ufo.ufoView");

	lua_pushvalue(g_ufo_lua_state, -1);
	lua_setfield(g_ufo_lua_state, -2, "__index");

	luaL_register(g_ufo_lua_state, 0, viewlib);
	luaL_register(g_ufo_lua_state, "ufoView", viewlib_c);

	return 1;
}